package com.itheima.consumer.mq;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.time.LocalTime;
import java.util.Map;


@Slf4j
@Component
public class SpringRabbitListener {


    // 利用RabbitListener来声明要监听的队列信息
    // 将来一旦监听的队列中有了消息，就会推送给当前服务，调用当前方法，处理消息。
    // 可以看到方法体中接收的就是消息体的内容
    @RabbitListener(queues = "simple.queue")
    public void listenSimpleQueueMessage(String msg) throws InterruptedException {
        System.out.println("spring 消费者接收到消息：【" + msg + "】");
    }

    /*WorkQueues模型*/
    @RabbitListener(queues = "work.queue")
    public void listenWorkQueue1(String msg) throws InterruptedException {
        System.out.println("消费者1接收到消息：【" + msg + "】" + LocalTime.now());
        Thread.sleep(20);
    }

    @RabbitListener(queues = "work.queue")
    public void listenWorkQueue2(String msg) throws InterruptedException {
        System.err.println("消费者2........接收到消息：【" + msg + "】" + LocalTime.now());
        Thread.sleep(200);

    }

    /*fanout交换机*/
    @RabbitListener(queues = "fanout.queue1")
    public void listenFanoutQueue1(String message) {
        System.out.println("消费者1接收到fanout.queue1的消息：【" + message + "]");
    }

    @RabbitListener(queues = "fanout.queue2")
    public void listenFanoutQueue2(String message) {
        System.out.println("消费者2接收到fanout.queue2的消息：【" + message + "]");
    }

    /*.Direct交换机*/
   /* @RabbitListener(queues = "direct.queue1")
    public void listenDirectQueue1(String msg) {
        System.out.println("消费者1接收到direct.queue1的消息：【" + msg + "】");
    }

    @RabbitListener(queues = "direct.queue2")
    public void listenDirectQueue2(String msg) {
        System.out.println("消费者2接收到direct.queue2的消息：【" + msg + "】");
    }
*/
    /*Topic交换机*/
    @RabbitListener(queues = "topic.queue1")
    public void listenTopicQueue1(String msg){
        System.out.println("消费者1接收到topic.queue1的消息：【" + msg + "】");
    }

    @RabbitListener(queues = "topic.queue2")
    public void listenTopicQueue2(String msg){
        System.out.println("消费者2接收到topic.queue2的消息：【" + msg + "】");
    }


    //基于@Bean的方式声明队列和交换机比较麻烦，Spring还提供了基于注解方式来声明。
    @RabbitListener(bindings = @QueueBinding(
            value =@Queue(name = "direct.queue1"),
            exchange = @Exchange(name = "hmall.direct",type = ExchangeTypes.DIRECT),
            key = {"red", "blue"}
    ))
    public void listenDirectQueue11(String msg){
        System.out.println("消费者1接收到direct.queue1的消息：【" + msg + "】");
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "direct.queue2"),
            exchange = @Exchange(name = "hmall.direct", type = ExchangeTypes.DIRECT),
            key = {"red", "yellow"}
    ))
    public void listenDirectQueue12(String msg){
        System.out.println("消费者2接收到direct.queue2的消息：【" + msg + "】");
    }

    //消息转换器 使用Jackson  消费者接收Object
    @RabbitListener(queues = "object.queue")
    public void listenSimpleQueueMessage(Map<String, Object> msg) throws InterruptedException {
        System.out.println("消费者接收到object.queue消息：【" + msg + "】");
    }


    //LazyQueue
    //Lazy Queues的模式，也就是惰性队列。惰性队列的特征如下：
    //- 接收到消息后直接存入磁盘而非内存
    //- 消费者要消费消息时才会从磁盘中读取并加载到内存（也就是懒加载）
    //- 支持数百万条的消息存储
    @RabbitListener(queuesToDeclare = @Queue(
            name = "lazy.queue",
            durable = "true",
            arguments = @Argument(name = "x-queue-mode", value = "lazy")
    ))
    public void listenLazyQueue(String msg){
        log.info("接收到 lazy.queue的消息：{}", msg);
    }

    //获取消息中的唯一ID  Message对象接受参数
    @RabbitListener(queues = "simple.queue")
    public void listenSimpleQueueMessageID(Message message) throws InterruptedException {
        System.out.println("spring 消费者接收到消息ID为：【" + message.getMessageProperties().getMessageId() + "】");
        System.out.println("spring 消费者接收到消息：【" + new String(message.getBody()) + "】");
    }

    //死信交换机  定义死信交换机 和 队列 和key绑定 和消费者
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "dlx.queue",durable = "true"),
            exchange = @Exchange(name = "dlx.direct", type = ExchangeTypes.DIRECT),
            key = {"hi"}
    ))
    public void listenDlxQueue(String msg){
        System.out.println("消费者接收到dlx.queue的消息：【" + msg + "】");
    }



}
